package com.hgl.bi.web.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.hgl.bi.common.constant.ErrorCode;
import com.hgl.bi.common.manager.CaptchaManager;
import com.hgl.bi.common.manager.RedisManager;
import com.hgl.bi.common.model.vo.CaptchaVo;
import com.hgl.bi.common.model.vo.R;
import com.hgl.bi.common.utils.AssertUtil;
import com.hgl.bi.web.model.dto.LoginDto;
import com.hgl.bi.web.model.dto.RegisterDto;
import com.hgl.bi.web.model.dto.UserInfoDto;
import com.hgl.bi.web.model.vo.LoginInfoVo;
import com.hgl.bi.web.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

/**
 * @program: BI
 * @description: 用户登录控制层
 * @author: hgl
 * @create: 2025-02-12 18:37
 */
@Tag(name = "登录模块")
@Slf4j
@RestController
public class LoginController {

    @Autowired
    private UserService userService;

    @Autowired
    private CaptchaManager captchaManager;

    @Autowired
    private RedisManager redisManager;

    /**
     * 新用户注册
     *
     * @param registerDto 注册信息
     * @return 提示信息
     * @author hgl
     */
    @Operation(summary = "注册", tags = "登录模块")
    @PutMapping("/register")
    public R<String> register(@RequestBody RegisterDto registerDto) {
        // 非空校验
        AssertUtil.notNull(registerDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 注册
        userService.register(registerDto);
        return R.ok("注册成功");
    }

    /**
     * 用户登录
     *
     * @param loginDto 登录信息
     * @return 提示信息
     * @author hgl
     */
    @Operation(summary = "登录", tags = "登录模块")
    @PostMapping("/login")
    public R<String> login(@RequestBody LoginDto loginDto) {
        // 非空校验
        AssertUtil.notNull(loginDto, ErrorCode.REQUEST_PARAM_ERROR);
        // 更新状态
        String token = userService.login(loginDto);

        return R.success(token);
    }

    /**
     * 用户退出登录
     *
     * @return 提示信息
     * @author hgl
     */
    @Operation(summary = "退出", tags = "登录模块")
    @PostMapping("/logout")
    public R<String> logout(@RequestHeader("satoken") String satoken) {
        // 获取当前登录用户id
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);
        Long userId = userInfo.getId();
        // 更新状态
        userService.logout(userId);
        // 退出登录
        StpUtil.logout(userId);

        // 删除用户信息
        Boolean deleted = redisManager.delete("satoken:" + satoken);
        log.info("删除用户信息：" + deleted);
        return R.ok("退出成功");
    }

    /**
     * 用户退出登录
     *
     * @return 提示信息
     * @author hgl
     */
    @Operation(summary = "获取登录信息", tags = "登录模块")
    @GetMapping("/info")
    public R<LoginInfoVo> getLoginInfo(@RequestHeader("satoken") String satoken) {
        UserInfoDto userInfo = (UserInfoDto) redisManager
                .get("satoken:" + satoken, UserInfoDto.class);

        // 返回登录信息
        return R.success(new LoginInfoVo(userInfo.getUsername(),
                userInfo.getAvatar(), userInfo.getRole()));
    }

    /**
     * 获取验证码
     *
     * @return 验证码图片的base64编码和key
     * @author hgl
     */
    @Operation(summary = "获取图形验证码", tags = "登录模块")
    @GetMapping("/captcha")
    public R<CaptchaVo> getCaptcha() {
        String key = UUID.randomUUID().toString();
        String captcha = captchaManager.getNumberCaptcha(key);
        return R.success(new CaptchaVo(captcha, key));
    }

    /**
     * 检查token是否有效
     *
     * @return 提示信息
     * @author hgl
     */
    @Operation(summary = "检查token是否有效", tags = "登录模块")
    @GetMapping("/check-token")
    public R<String> checkToken(@RequestHeader("satoken") String satoken) {
        AssertUtil.notNull(satoken, ErrorCode.REQUEST_PARAM_ERROR);
        userService.checkToken(satoken);
        return R.success("token有效");
    }
}
